package gang.org.springframework.framework.annotation;

import gang.org.springframework.boot.autoconfigure.GImport;
import gang.org.springframework.boot.autoconfigure.GangAutoConfigurationImportSelector;
import gang.org.springframework.boot.autoconfigure.GangDeferredImportSelector;
import gang.org.springframework.boot.autoconfigure.GangImportSelector;
import gang.org.springframework.framework.bean.GangAnnotatedBeanDefinition;
import gang.org.springframework.framework.bean.GangBeanDefinition;
import gang.org.springframework.framework.bean.GangBeanDefinitionHolder;
import gang.org.springframework.framework.core.annotation.GangAnnotationUtils;
import gang.org.springframework.framework.core.type.classreading.GangMetadataReader;
import gang.org.springframework.framework.core.type.classreading.GangMetadataReaderFactory;
import gang.org.springframework.framework.io.GangResourceLoader;
import gang.org.springframework.framework.metadata.GangAnnotationAttributes;
import gang.org.springframework.framework.metadata.GangAnnotationMetadata;
import gang.org.springframework.framework.metadata.GangStandardAnnotationMetadata;
import gang.org.springframework.framework.support.GangBeanDefinitionRegistry;
import gang.org.springframework.framework.support.GangBeanNameGenerator;
import gang.org.springframework.framework.type.GangMethodMetadata;
import gang.org.springframework.framework.util.GangClassUtils;
import gang.org.springframework.framework.util.GangParserStrategyUtils;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.util.*;
import java.util.function.Predicate;

/**
 * @author gang.chen
 * @description 业务意义
 *      1> GangConfigurationClassParser 解析JAVA的类
 *      2> 解析方法入口一 parse(Set<GangBeanDefinitionHolder> beanDefinitionHolders)
 *      3> 解析方法入口二 parse(GangAnnotationMetadata annotationMetadata, String beanName)
 * @Call
 *  调用逻辑一
 *      1>parse(Set<GangAnnotationMetadata>)
 *          >parse(GangAnnotationMetadata,String)
 *              >processConfigurationClass(GangConfigurationClass, Predicate)
 *                  >doProcessConfigurationClass(GangConfigurationClass, GangSourceClass, Predicate)
 *              >this.configurationClass.put(GangConfigurationClass, GangConfigurationClass)
 *       >DeferredImportSelectorHandler.process()
 *   调用逻辑二
 *      2>DeferredImportSelectorHandler.process()
 *          >DeferredImportSelectorGroupingHandler.processGroupImports()
 *              >processImport(GangConfigurationClass,GangSourceClass,Collection<GangSourceClass>,Predicate)
 *                  >processConfigurationClass(GangConfigurationClass, Predicate)
 *                      >doProcessConfigurationClass(GangConfigurationClass, GangSourceClass, Predicate)
 *                  >this.configurationClass.put(GangConfigurationClass, GangConfigurationClass)
 * @Date 2021/6/19 13:43
 */
public class GangConfigurationClassParser {

    private final GangImportStack importStack = new GangImportStack();

    private final GangBeanDefinitionRegistry registry;

    private final GangMetadataReaderFactory metadataReaderFactory;

    private final Map<GangConfigurationClass,GangConfigurationClass> configurationClasses = new LinkedHashMap<>();

    private final DeferredImportSelectorHandler deferredImportSelectorHandler = new DeferredImportSelectorHandler();

    public Set<GangConfigurationClass> getConfigurationClasses() {
        return this.configurationClasses.keySet();
    }

    public final GangComponentScanAnnotationParser componentScanParser;

    public static final Predicate<String> DEFAULT_EXCLUSION_FILTER = className -> (className.startsWith("java.lang.annotation.") || className.equals("gang.org.springframework.framework.annotation.GComponent"));

    private final GangSourceClass objectSourceClass = new GangSourceClass(Object.class);
    public GangConfigurationClassParser(GangMetadataReaderFactory metadataReaderFactory,
                                        Object problemReport,
                                        Object environment,
                                        GangResourceLoader resourceLoader,
                                        GangBeanNameGenerator componentScanBeanNameGenerator,
                                        GangBeanDefinitionRegistry registry)
    {
        this.metadataReaderFactory = metadataReaderFactory;
        this.registry = registry;
        this.componentScanParser = new GangComponentScanAnnotationParser(environment, resourceLoader,componentScanBeanNameGenerator,registry);
    }

    /**
     * @param configCandidates {@link Set<GangBeanDefinitionHolder>}
     * */
    public void parse(Set<GangBeanDefinitionHolder> configCandidates)
    {
        for (GangBeanDefinitionHolder holder : configCandidates) {

            GangBeanDefinition bd = holder.getBeanDefinition();

            if (bd instanceof GangAnnotatedBeanDefinition)
            {
                parse(((GangAnnotatedBeanDefinition)bd).getMetadata(),holder.getBeanName());
            }
        }

        /**
         * 业务意义
         * 处理spring.factories配置类Bean
         * */
        this.deferredImportSelectorHandler.process();
    }

    /**
     * TODO
     * @param metadata {@link GangStandardAnnotationMetadata}
     * @param beanName bean name
     * 业务意义
     * 对项目主类SpringbootManualApplication进行解析
     * */
    protected final void parse(GangAnnotationMetadata metadata, String beanName)
    {
        processConfigurationClass(new GangConfigurationClass(beanName,metadata),null);
    }

    /**
     * TODO
     * @param configClass {@link GangConfigurationClass}
     * */
    protected void processConfigurationClass(GangConfigurationClass configClass, Object filter)
    {
        /**
         * 业务意义
         * 场景一
         * 项目启动类SpringbootManualApplication 业务封装为 GangSourceClass；在此业务场景下，操作的对象Class字节码
         *
         * 场景二
         * 自动配置类GangDispatcherServletAutoConfiguration 业务封装 GangSourceClass；在此业务场景下，操作的对象Class文件目录
         *
         * 无论是项目启动类SpringbootManualApplication，还是自动装配类E.g GangDispatcherServletAutoConfiguration 等类都会被
         * 封装为GangConfigurationClass-> GangBeanDefinition
         * */
        GangSourceClass sourceClass = asSourceClass(configClass, null);

        do{
            sourceClass = doProcessConfigurationClass(configClass, sourceClass, null);
        }
        while (sourceClass != null);

        /**
         * 业务意义
         * 1，主启动类SpringbootManualApplication 封装为GangConfigurationClass
         * 2，工厂类 "ALL" 封装为GangConfigurationClass
         * 3，在下一个业务处理结点，将GangConfigurationClass转为BeanDefinition
         * */
        this.configurationClasses.put(configClass,configClass);
    }

    //TODO
    protected final GangSourceClass doProcessConfigurationClass(GangConfigurationClass configClass, GangSourceClass sourceClass, Object filter)
    {
        /*
         * 处理场景一：Component注解解析
         * 1）原注解 Configuration = 映射注解{Component, Indexed}, 注解了@Configurtion则可理解为注解了@Component
         * 2）递归处理工厂类中的内部类
         * 2.1）处理WebMvcAutoConfiguration
         * */
        if (configClass.getMetadata().isAnnotated(GComponent.class.getName())) {
            processMemberClasses(configClass, sourceClass, null);
        }

        //处理场景二：@PropertySource注解解析

        //处理场景三：@ComponentScan注解解析 业务类处理,非框架类的Bean初始化
        Set<GangAnnotationAttributes> componentScans = GangAnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), GComponentScans.class, GComponentScan.class);
        //TODO
        if (!componentScans.isEmpty()) {
            for (GangAnnotationAttributes componentScan : componentScans) {
                Set<GangBeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());

                //TODO 循环解析
            }
        }

        //处理场景四：@Import注解解析
        processImports(configClass,sourceClass,getImports(sourceClass),null,true);

        //处理场景五：@ImportResource注解解析

        //处理场景六：@Bean methods注解解析
        Set<GangMethodMetadata> methodMetadataSet = retrieveBeanMethodMetadata(sourceClass);
        for (GangMethodMetadata methodMetadata : methodMetadataSet) {
            configClass.addBeanMethod(new GangBeanMethod(methodMetadata,configClass));
        }

        //处理场景七： Process default methods on interfaces

        /**
         * 处理场景八： Process superclass, if any
         * */
        if (sourceClass.getMetadata().hasSupperClass()) {
            String superClassName = sourceClass.getMetadata().getSuperClassName();
            /**
             * TODO 业务判断 后续补全 业务意义
             * 1）循环处理
             * 2）当前类Bean method 属于当前类；父类Bean method 属于当前类
             * 3）执行while循环，直致当前类没有父类为至
             * 4）父类的Bean方法，封装为BeanMethod，存储于当前类的beanMethods属性中
             * */
            if (superClassName != null && !superClassName.startsWith("java")){
                return sourceClass.getSupperClass();
            }
        }
        return null;
    }

    /**
     * TODO
     * 业务意义
     * @param configClass {@link GangConfigurationClass} 指向主启动类SpringbootManualApplication
     * @param currentSourceClass {@link GangSourceClass} 指向主启动类SpringbootManualApplication
     * @param importCandidates {@link Set} 指向工厂配置类
     * @param exclusionClass null
     * @param checkForCircularImports true
     * */
    private void processImports(GangConfigurationClass configClass,
                                GangSourceClass currentSourceClass,
                                Collection<GangSourceClass> importCandidates,
                                Object exclusionClass,
                                boolean checkForCircularImports)
    {
        for (GangSourceClass candidate : importCandidates) {
            /*
             * TODO
             * 执行 GangAutoConfigurationImportSelector
             * */
            if (candidate.isAssignable(GangImportSelector.class)) {
                Class<?> candidateClass = candidate.loadClass();

                GangImportSelector selector = GangParserStrategyUtils.instantiateClass(candidateClass,
                        GangImportSelector.class,
                        null,
                        null,
                        this.registry);
                /**
                 * TODO
                 * configClass -> 项目主类SpringbootManualApplication封装配置文件
                 * */
                this.deferredImportSelectorHandler.handle(configClass,(GangDeferredImportSelector) selector);
            }
            else {
                /*
                 * TODO
                 * 处理->spring.factories中配置文件类
                 * */
                this.importStack.registerImport(null,null);
                processConfigurationClass(candidate.asConfigClass(configClass),null);
            }

        }


    }

    private class DeferredImportSelectorHandler{

        private List<DeferredImportSelectorHolder> deferredImportSelectors = new ArrayList<>();
        /**
         * @param configClass {@link GangConfigurationClass}
         * @param importSelector {@link gang.org.springframework.boot.autoconfigure.GangAutoConfigurationImportSelector}
         * */
        public void handle(GangConfigurationClass configClass, GangDeferredImportSelector importSelector)
        {
            DeferredImportSelectorHolder holder = new DeferredImportSelectorHolder(configClass,importSelector);
            if (deferredImportSelectors==null) {
                //TODO
            }else {
                this.deferredImportSelectors.add(holder);
            }
        }

        /**
         * 业务意义，对实现顶级导入接口所有类，进行自动装配类的载入
         * 1， >parse(Set<GangBeanDefinitionHolder>)
         *      >parse(GangAnnotationMetadata, String)
         *          >processConfigurationClass(GangConfigurationClass, Object)
         *              >doProcessConfigurationClass(GangConfigurationClass,GangSourceClass,Object)
         *                  >processImport(GangConfigurationClass,GangSourceClass,Collection<GangSourceClass>,Object,boolean)
         *                      >DeferredImportSelectorHandler.handle(GangConfigurationClass,GangDeferredImportSelector);
         * 以上业务处理，初始化List<DeferredImportSelectorHolder>集合 -> deferredImportSelectors
         *
         * 2，实现顶级导入的类可能有多个
         * */
        public void process(){
            /**
             * 1，DeferredImportSelectorHolder
             *      1.1 configurationClass -> 启动类SpringbootManualApplication封装
             *      1.2 importSelector-> GangAutoConfigurationImportSelector导入类
             * */
            List<DeferredImportSelectorHolder> deferredImportSelectors = this.deferredImportSelectors;
            if (deferredImportSelectors !=null) {
                /**
                 * TODO
                 * 1，初始化DeferredImportSelectorGroupingHandler handler
                 * 2，初始化DeferredImportSelectorGroupingHandler.Map<Object, DeferredImportSelectorGrouping> =>groupings
                 * */
                DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
                /**
                 * TODO
                 * 业务意义
                 * 1，DeferredImportSelectorHolder实例为参数
                 * 2，DeferredImportSelectorGroupingHandler实例方法register
                 * */
                deferredImportSelectors.forEach(handler::register);
                //TODO
                handler.processGroupImport();
            }
        }
    }

    private class DeferredImportSelectorHolder
    {
        private final GangConfigurationClass configurationClass;
        private final GangDeferredImportSelector importSelector;

        public DeferredImportSelectorHolder(GangConfigurationClass configurationClass, GangDeferredImportSelector importSelector) {
            this.configurationClass = configurationClass;
            this.importSelector = importSelector;
        }

        public GangDeferredImportSelector getImportSelector() {
            return importSelector;
        }

        public GangConfigurationClass getConfigurationClass() {
            return configurationClass;
        }
    }

    /**
     * 业务意义
     * 1， 1.1 方法一 register(DeferredImportSelectorHolder)
     *     1.2 准备业务对象Map<Object,DeferredImportSelectorGrouping>
     *     2.3 DeferredImportSelectorGrouping是一个中间对象，对AutoConfigurationGroup的封装
     * */
    private class DeferredImportSelectorGroupingHandler
    {
        /**
         * 业务意义
         * 1）grouping is Map
         *  1.1 key   - AutoConfigurationGroup
         *  1.2 value - DeferredImportSelectorGrouping
         * */
        private final Map<Object, DeferredImportSelectorGrouping> groupings = new LinkedHashMap<>();
        private final Map<GangAnnotationMetadata,GangConfigurationClass> configurationClasses = new HashMap<>();

        //TODO
        public void register(DeferredImportSelectorHolder deferredImportSelectorHolder){
            /**
             * 1，TODO
             * 2，group->AutoConfigurationGroup
             * */
            Class<? extends GangDeferredImportSelector.Group> group = deferredImportSelectorHolder.getImportSelector().getImportGroup();

            /*
             *  业务意义：初始化 DeferredImportSelectorGrouping 对象
             *  1.1，group->AutoConfigurationGroup
             *  1.2，List<DeferredImportSelectorHolder>
             * */
            DeferredImportSelectorGrouping grouping = groupings.computeIfAbsent(
                    group != null ? group:deferredImportSelectorHolder,
                    key -> new DeferredImportSelectorGrouping(createGroup(group))
            );

            grouping.add(deferredImportSelectorHolder);

            this.configurationClasses.put(deferredImportSelectorHolder.getConfigurationClass().getMetadata(), deferredImportSelectorHolder.getConfigurationClass());
        }

        /**
         * 业务意义
         * 1，groupings-> Map<Object, DeferredImportSelectorGrouping>-> register方法中初始化
         *  1.1 K ->Object ->AutoConfigurationGroup
         *  1.2 V ->new DeferredImportSelectorGrouping(createGroup(group))
         *
         * 2，getImport()
         *  2.1 List<DeferredImportSelectorHolder> deferredImports = new ArrayList<>()
         *  2.2 getImport() 导入资源配置文件的入口
         *
         *  3，org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
         *  3.1，Configuration注解
         *  3.2，Bean注解(指定方法)
         * */
        public void processGroupImport()
        {
            /**
             * 业务意义
             * 1）DeferredImportSelectorGrouping 是对 AutoConfigurationGroup 封装
             * 2）AutoConfigurationGroup 是Springboot处理工厂资源文件的入口
             * */
            for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {

                grouping.getImport().forEach(entry -> {

                    GangConfigurationClass configurationClass = this.configurationClasses.get(entry.getMetadata());

                    /**
                     * TODO
                     * 业务意义
                     * currentSourceClass 指向主启动类 SpringbootManualApplication，由该类来引导加载工厂类
                     * */
                    GangSourceClass currentSourceClass = asSourceClass(configurationClass, null);

                    /**
                     * TODO
                     * 业务意义
                     * importSourceClass 工厂类全路径名
                     * */
                    final GangSourceClass importSourceClass = asSourceClass(entry.getImportClassName(), null);

                    final Set<GangSourceClass> importCandidates = Collections.singleton(importSourceClass);

                    processImports(configurationClass,
                            currentSourceClass,
                            importCandidates,
                            null,
                            false);
                });
            }


        }

        /**
         * TODO
         * @param type {@link GangAutoConfigurationImportSelector.AutoConfigurationGroup}
         *
         * 业务意义
         * 1，实例化AutoConfigurationGroup, 其处理自动装配资源文件spring.factories
         * 2，aware接口方法回调，为AutoConfigurationGroup实例，设置属性ClassLoader
         * */
       private GangDeferredImportSelector.Group createGroup(Class<? extends GangDeferredImportSelector.Group> type){

            Class<? extends GangDeferredImportSelector.Group> effectiveType = type != null ? type: null;
            return GangParserStrategyUtils.instantiateClass(effectiveType,
                    GangDeferredImportSelector.Group.class,
                    null,
                    null,
                    registry);
       }
    }

    /**
     * 业务意义
     * 1，对Group接口， AutoConfigurationGroup实现类的封装
     * */
    private static class DeferredImportSelectorGrouping
    {
        /**
         * DeferredImportSelectorGroupingHandler#register
         * 属性group/deferredImport是在register方法中被初始化
         * */
        private final GangDeferredImportSelector.Group group;
        private final List<DeferredImportSelectorHolder> deferredImports = new ArrayList<>();

        /**
         * 业务意义：初始化对象
         * @param group {@link gang.org.springframework.boot.autoconfigure.GangAutoConfigurationImportSelector.AutoConfigurationGroup}
         * */
        public DeferredImportSelectorGrouping(GangDeferredImportSelector.Group group)
        {
            this.group = group;
        }

        public Iterable<GangDeferredImportSelector.Group.Entry> getImport(){

            for (DeferredImportSelectorHolder importSelectorHolder : this.deferredImports) {
                //实现spring.factories文件的解析
                this.group.process(importSelectorHolder.getConfigurationClass().getMetadata(),importSelectorHolder.getImportSelector());
            }
            //创建Entry对象
            return group.selectImport();
        }

        public void add(DeferredImportSelectorHolder importSelectorHolder){
            this.deferredImports.add(importSelectorHolder);
        }
    }

    //TODO
    public static class GangImportStack extends ArrayDeque<GangConfigurationClass> implements GangImportRegistry{

        //TODO
        public void registerImport(Object importingClass, String importedClass){

        }
    }


    //TODO
    private class GangSourceClass {
        /**
         * source 会接收多种数据类型
         * 1）场景一 class类
         * 2）场景二 GangSimpleMetadataReader类
         * */
        private final Object source;
        private final GangAnnotationMetadata metadata;

        public GangSourceClass(Object source) {
            this.source = source;

            if (source instanceof Class){
                this.metadata = GangAnnotationMetadata.introspect((Class<?>)source);
            }else{
                this.metadata = ((GangMetadataReader)source).getAnnotationMetadata();
            }

        }

        //TODO
        public Set<GangSourceClass> getAnnotations()
        {
            Set<GangSourceClass> result = new LinkedHashSet<>();

            if (this.source instanceof Class) {
                Class<?> sourceClass = (Class<?>) this.source;
                for (Annotation ann : sourceClass.getDeclaredAnnotations())
                {
                    Class<? extends Annotation> anyType = ann.annotationType();
                    String name = anyType.getName();
                    //#######################################################
                    //JDK原生注解过滤，比如 java.lang.annotation.Target
                    //其余spring定义的注解，解析生成GangSourceClass
                    //#######################################################
                    if (!name.startsWith("java"))
                    {
                        result.add(asSourceClass(anyType,null));
                    }
                }
            }
            else {
                /**
                 *#######################################################
                 * 举例说明其业务意义
                 * 1）ServletWebServerFactoryAutoConfiguration.java 该类从spring-autoconfigure-metadata.properties配置类中读取
                 * 2）其它业务意义就在于，从ServletWebServerFactoryAutoConfiguration.java类中获取注解字符
                 * 2.1 字符 org.springframework.boot.autoconfigure.AutoConfiguration
                 * 2.2 字符 org.springframework.boot.autoconfigure.AutoConfigureOrder
                 * 2.3 字符 org.springframework.boot.autoconfigure.condition.ConditionalOnClass
                 * 2.4 字符 org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication
                 * 2.5 字符 org.springframework.boot.context.properties.EnableConfigurationProperties
                 * 2.6 字符 org.springframework.context.annotation.Import
                 *#######################################################
                 * */
                //TODO
                for (String className : metadata.getAnnotationTypes()) {

                    if (null != className && !className.startsWith("java")) {

                        try {
                            result.add(getRelated(className));
                        }
                        catch (Throwable ex){
                            //TODO
                        }
                    }

                }
            }
            /**
             * 如果条件都不符合，则返回EmptySet
             * */
            return result;
        }

        public GangAnnotationMetadata getMetadata()
        {
            return this.metadata;
        }

        /**
         * 业务意义对配置类中注解进行读取，举例说明
         * 1）配置类 GangServletWebServerFactoryAutoConfiguration.java -> SourceClass
         * 2)读取注解 @GImport
         *
         * @param annType String value is "gang.org.springframework.boot.autoconfigure.GImport"
         * @param attribute String value is "value"
         * */
        public Collection<GangSourceClass> getAnnotationAttributes(String annType, String attribute)
        {
            /**
             * this -> ServletWebServerFactoryAutoConfiguration -> SourceClass -> SimpleAnnotationMetadata
             * */
            Map<String, Object> annotationAttribute = this.metadata.getAnnotationAttribute(annType, true);
            //TODO
            if(annotationAttribute == null || annotationAttribute.size() ==0 || !annotationAttribute.containsKey(attribute)){
                return Collections.emptySet();
            }
            String[] ClassNames = (String[]) annotationAttribute.get(attribute);
            Set<GangSourceClass> result = new LinkedHashSet<>();
            for (String className : ClassNames) {
                result.add(getRelated(className));
            }
            return result;
        }

        private GangSourceClass getRelated(String className){
            /**
             * 场景一：处理class类
             * */
            if (this.source instanceof Class){
                Class<?> clazz = GangClassUtils.forName(className,((Class<?>) this.source).getClassLoader());
                return asSourceClass(clazz,null);
            }

            /**
             * 场景二：处理SimpleMetadataReader
             * */

            return asSourceClass(className, DEFAULT_EXCLUSION_FILTER);
        }

        //TODO
        public boolean isAssignable(Class<?> clazz){
            if (this.source instanceof Class) {
                return true;
            }
            return false;
        }

        /**
         * 业务意义
         * 业务场景一 非递归解析
         * 1，SpringbootManualApplication主类，由自身引入封装为ConfigurationClass
         *
         * 业务场景二 递归解析
         * 1，WebMvcAutoConfiguration工厂类，由自身引入封装为ConfigurationClass
         * 2，EnableWebMvcConfiguration所属WebMvcAutoConfiguration内部类，由WebMvcAutoConfiguration引入封装为ConfigurationClass
         * */
        public GangConfigurationClass asConfigClass(GangConfigurationClass importedBy){
            return new GangConfigurationClass((GangMetadataReader)this.source,importedBy);
        }

        public Class<?> loadClass(){
            return (Class<?>) this.source;
        }

        public Collection<GangSourceClass> getMemberClasses(){
            /**
             * 业务意义 TODO
             * 场景一 获取工厂类子类
             * 1） source -> GangSimpleMetadataReader
             * */
            Object sourceToProcess = this.source;

            /**
             * 场景二 ？
             * */
            if (sourceToProcess instanceof Class) {
                //TODO
            }
            /**
             * 业务意义
             * 1）GangMetadataReader -> GangSimpleMetadataReader
             * 2）ASM字节码解析
             * 3）工厂主类，内部类，由SAM解析获取
             * */
            GangMetadataReader metadataReader = (GangMetadataReader) sourceToProcess;

            String[] memberClassNames = metadataReader.getClassMetadata().getMemberClassNames();

            ArrayList<GangSourceClass> members = new ArrayList<>(memberClassNames.length);

            /**
             * 业务意义
             * 1）工厂主类中所有内部子类
             * 2）每个内部子类封装SourceClass
             * */
            for (String memberClassName : memberClassNames) {
                members.add(asSourceClass(memberClassName, null));
            }
            return members;
        }

        /**
         * 业务意义 TODO
         * */
        public GangSourceClass getSupperClass(){
            if (this.source instanceof Class){
                //TODO
            }
            return asSourceClass(((GangMetadataReader)this.source).getClassMetadata().getSuperClassName(),null);
        }


    }

    /**
     * 业务意义
     * 创建 GangSourceClass实例
     * */
    private GangSourceClass asSourceClass(GangConfigurationClass configurationClass, Object filter)
    {
        /**
         * 场景一
         * GangAnnotationMetadata接口，实现类 GangStandardAnnotationMetadata
         * SpringbootManualApplication实现类->GangStandardAnnotationMetadata
         * 场景二
         * GangAnnotationMetadata接口，实现类 GangSimpleAnnotationMetadata
         * 工产实现类->GangSimpleAnnotationMetadata
         * */
        GangAnnotationMetadata metadata = configurationClass.getMetadata();
        if (metadata instanceof GangStandardAnnotationMetadata) {
            return asSourceClass(((GangStandardAnnotationMetadata)metadata).getIntrospectedClass(),null);
        }
        return asSourceClass(metadata.getClassName(),null);
    }

    //TODO
    GangSourceClass asSourceClass(Class<?> classType, Object filter)
    {
        return new GangSourceClass(classType);
    }

    //TODO
    GangSourceClass asSourceClass(String className, Predicate<String>filter){

        /**
         * 业务意义
         * 1）当指定类所在包名为：java.lang.annotation 下，返回Object SourceClass
         * 2) 当指定类所在包名为：org.springframework.stereotype下，返回 Object SourceClass
         * */
        if (null != filter){
            //TODO
            if (className == null || filter.test(className)) {
                return this.objectSourceClass;
            }
        }

        final GangMetadataReader metadataReader = this.metadataReaderFactory.getMetadataReader(className);
        return new GangSourceClass(metadataReader);
    }

    /**
     * 业务意义
     * 1）传入的原始类为：SpringbootManualApplication
     * 2）通过递归的方式，获取主类的注解：
     *    2.1）@GSpringBootApplication
     *    2.2）@GEnableAutoConfiguration
     *    2.3）@GImport
     * 3）最终把以上注解类包装为源类GangSourceClass
     * @param sourceClass GangSourceClass类
     * */
    private Set<GangSourceClass> getImports(GangSourceClass sourceClass)
    {
        Set<GangSourceClass> imports = new LinkedHashSet<>();
        Set<GangSourceClass> visited = new LinkedHashSet<>();
        collectImports(sourceClass,imports,visited);
        return imports;
    }

    //TODO
    private void collectImports(GangSourceClass sourceClass,Set<GangSourceClass> imports, Set<GangSourceClass> visited)
    {
        //#############################################################
        //递归获取注解
        //1> SpringbootManualApplication 返回->GSpringBootApplication
        //
        //2> GSpringBootApplication      返回->Target(原生注解过滤)
        //                               返回->Retention(原生注解过滤)
        //                               返回->Inherited(原生注解过滤)
        //                               返回->GEnableAutoConfiguration
        //
        //3> GEnableAutoConfiguration    返回->Target(原生注解过滤)
        //                               返回->Retention(原生注解过滤)
        //                               返回->Inherited(原生注解过滤)
        //                               返回->GImport
        //
        //4> GImport(跳出递归)             返回->Target(原生注解过滤)
        //                               返回->Retention(原生注解过滤)
        //-结束-
        //#############################################################
        if (visited.add(sourceClass))
        {
            /**
             * 业务意义说明
             * 1）对于配置类：ServletWebServerFactoryAutoConfiguration 读取spring-autoconfigure-metadata.properties获取到该类时
             * 2）要获取该类中6个注意分别是
             * 2.1 @AutoConfiguration
             * 2.2 @AutoConfigureOrder
             * 2.3 @ConditionalOnClass
             * 2.4 @ConditionalOnWebApplication
             * 2.5 @EnableConfigurationProperties
             * 2.6 @Import
             *
             * 以上6个注解都会被封装为 SourceClass 对象
             * */
            Set<GangSourceClass> gangSourceClasses = sourceClass.getAnnotations();
            for (GangSourceClass annotation : gangSourceClasses)
            {
                String annName = annotation.getMetadata().getClassName();
                if (!annName.equals(GImport.class.getName()))
                {
                    collectImports(annotation,imports,visited);
                }
            }
            imports.addAll(sourceClass.getAnnotationAttributes(GImport.class.getName(), "value"));
        }
    }

    /**
     * TODO 业务意义
     * 1）工厂主类，获取内部子类
     * 2）重新对子类解析
     * 2.1）处理父类：WebMvcAutoConfiguration
     * 2.2）处理子类：EnableWebMvcConfiguration
     * @param configClass 指向-> WebMvcAutoConfiguration
     * @param sourceClass 指向-> WebMvcAutoConfiguration
     * */
    private void processMemberClasses(GangConfigurationClass configClass, GangSourceClass sourceClass, Predicate<String> filter){

        Collection<GangSourceClass> memberClasses = sourceClass.getMemberClasses();
        // 集合转换 & 条件过滤 TODO
        if (!memberClasses.isEmpty()) {
            List<GangSourceClass> sourceClassesCandidates = new ArrayList<>(memberClasses.size());
            for (GangSourceClass memberSourceClass : memberClasses) {
                //条件过滤 TODO
                sourceClassesCandidates.add(memberSourceClass);
            }

            //排序 TODO

            for (GangSourceClass candidate : sourceClassesCandidates) {
                if(1 == 2){
                    //TODO
                }else {
                    /**
                     * 业务意义，递归解析
                     * 1）GangWebMvcAutoConfiguration
                     * 2）GangEnableWebMvcConfiguration extends GangDelegatingWebMvcConfiguration extends GangWebMvcConfigurationSupport
                     * 3）@param candidate->SourceClass->EnableWebMvcConfiguration， 解析类
                     * 4）@param configClass->ConfigurationClass->importedBy->WebMvcAutoConfiguration，主引导类
                     * 5）@param configClass->ConfigurationClass-> EnableWebMvcConfiguration
                     * */
                    processConfigurationClass(candidate.asConfigClass(configClass), null);
                }
            }
        }

    }

    /**
     * 业务意义  TODO
     * */
    private Set<GangMethodMetadata> retrieveBeanMethodMetadata(GangSourceClass sourceClass){
        GangAnnotationMetadata original = sourceClass.getMetadata();
        Set<GangMethodMetadata> beanMethods = original.getAnnotatedMethods(GBean.class.getName());
        return beanMethods;
    }


}
